<script setup>
  import * as XLSX from 'xlsx';
  import * as echarts from 'echarts'
  import { watch, ref, reactive, onMounted } from 'vue';
  import { useRoute } from 'vue-router';
  import { ElMessage, ElMessageBox } from 'element-plus'
  import {
    GroupIndexes,
    GroupIndexChartOption,
    GroupIndexChartOptionSeason,
    GroupIndexChartOptionInterval,
    GroupIndexDetail,
    UpdateDataIndexReading,
  } from '@/api/datlib/datIndex'
  import { DataPrimaryIndex } from '@/api/datlib/variety'
  import { datetimeToString, dateIntervalDays } from '@/utils/datetimeUtils'
  const appRoute = useRoute()
    // 普通图形
  const chartOneBox = ref(null)
  let chartOne = null
  // 季节图形
  const chartTwoBox = ref(null)
  let chartTwo = null
  // 区间图形
  const chartThreeBox = ref(null)
  let chartThree = null

  // 图形的init配置
  const noDataChartOption = {
    graphic: {
      type: 'text',
      left: 'center',
      top: 'middle',
      silent: true,
      style: {
        fill: '#9d9d9d',
        fontWeight: 'bold',
        text: '暂无数据图形',
        fontSize: '17px'
      }
    }
  }
  
  // 当前显示的指标列表
  const currentIndexes = reactive({
    showList: [],
    hiddenList: [],
    isMore: false,
    showMore: false
  })

  // 查询指标具体数据的配置,图形参数
  const indexParams = reactive({
    dateRange: [],
    currentIndexId: -1,
    currentStackId: [],
    isStack: false,
    stackSeriesType: 'line',
    stackYasisPos: 0,
    chartCurrentDateRange: [],
    hasChartOption: false,
    chartCurrentOption: {}, // 当前图形配置
    seasonYears: 3,
    chartSeasonOption: {}, // 季节图形配置
    intervalYears: 3,
    chartIntervalOption: {}, // 区间图形配置
    currentTabName: 'first',
    tableCurrentData: [],
    tableCurrentColumns: [],
    tablePage: 1,
    tablePageSize: 50,
    tableStart: 0,
    tableEnd: 50,
    exportLoading: false
  })

  // 日期范围快速选择
  const dateRangeShortcuts = [
    {
      text: '本月',
      value: () => {
        const nt = new Date()
        return [datetimeToString(new Date(nt.getFullYear(), nt.getMonth(), 1)), datetimeToString(nt)]
      }
    },
    {
      text: '近六月',
      value: [datetimeToString(dateIntervalDays(new Date(), -180)), datetimeToString(new Date())]
    },
    {
      text: '近一年',
      value: [datetimeToString(dateIntervalDays(new Date(), -360)), datetimeToString(new Date())]
    }
  ]

  // 点击某个具体指标
  const toClickIndexItem = (idx, isHand) => {
    indexParams.currentIndexId = idx.id
    // 判断是否能叠加
    if (idx.is_stack && indexParams.isStack) {
      ElMessageBox.confirm(
        '该数据不支持图形堆叠!',
        '提示',
        {
          showCancelButton: false,
          confirmButtonText: '确定',
          type: 'warning',
          center: true,
        }
      ).then(() => {
        indexParams.isStack = false
        indexParams.currentIndexId = idx.id
        indexParams.currentStackId = [idx.id]
        getIndexDetailAndSetChartOption()
      })
    } else {
      if (indexParams.isStack && indexParams.hasChartOption) {
        // 有图形才能叠加
        indexParams.currentStackId.push(idx.id)
        getIndexDetailAndSetStackChart(
          indexParams.chartCurrentDateRange[0].replace(/-/g,''),
          indexParams.chartCurrentDateRange[1].replace(/-/g,'')
        )
      } else {
        indexParams.currentIndexId = idx.id
        indexParams.currentStackId = [idx.id]
        getIndexDetailAndSetChartOption()
      }
    }
    getSeasonChartOption() // 季节图形
    getIntervalChartOption() // 区间图形
    if (isHand) {
      UpdateDataIndexReading(idx.id)  // 主动点击的条目，添加访问次数
    }
  }

  // 点击查询按钮，指定日期范围再次主动查询指标数据
  const toQueryIndexData = () => {
    if (indexParams.currentStackId.length < 1) return
    indexParams.currentIndexId = indexParams.currentStackId[0]
    indexParams.currentStackId = [indexParams.currentIndexId]
    if (indexParams.isStack) {
      ElMessageBox.confirm(
        '时间段重置，不支持图形叠加',
        '提示',
        {
          showCancelButton: false,
          confirmButtonText: '确定',
          type: 'warning',
          center: true,
        }
      ).then(() => {
        indexParams.isStack = false
        getIndexDetailAndSetChartOption(
          indexParams.dateRange[0].replace(/-/g,''),
          indexParams.dateRange[1].replace(/-/g,'')
        )
      })
    } else {
      getIndexDetailAndSetChartOption(
        indexParams.dateRange[0].replace(/-/g,''),
        indexParams.dateRange[1].replace(/-/g,'')
      )
    }
  }

  // 查询组下的指标数据，设置图形1配置
  const getIndexDetailAndSetChartOption = (startDate=null, endDate=null) => {
    // 获取普通的配置
    GroupIndexChartOption(
      indexParams.currentStackId[0],
      startDate,
      endDate
    ).then((res) => {
      const resData = res.data
      if (!resData) {
        ElMessage.error({ message: res.message, type: 'error'})
        return
      }
      const indexObj = resData.description
      indexParams.hasChartOption = true
      indexParams.dateRange = [indexObj.start_date, indexObj.end_date]
      indexParams.chartCurrentDateRange = [indexObj.chart_start, indexObj.chart_end]
      indexParams.chartCurrentOption = resData.option
      chartOne.setOption(indexParams.chartCurrentOption, { notMerge: true })
      setTableDataWithChartOption() // 设置表格数据
    })
  }

  // 查询指标数据，并设置堆叠图形(图形1)
  const getIndexDetailAndSetStackChart = (startDate=null, endDate=null) => {
    const indexId = indexParams.currentStackId[indexParams.currentStackId.length -1]
    GroupIndexDetail(
      indexId,
      startDate,
      endDate
    ).then((res) => {
      const resData = res.data
      if (!resData) {
        ElMessage.error({ message: res.message, type: 'error'})
        return
      }
      // 进行图形配置的叠加
      const indexObj = resData.description
      const ddData = resData.detail
      const yAxisCount = indexParams.chartCurrentOption.yAxis.length
      if (indexParams.stackYasisPos === 1 && yAxisCount < 2) {
        indexParams.chartCurrentOption.yAxis.push({
          type: 'value',
          scale: true,
          name: indexObj.unit,
        })
      }
      // 数据转为字典模式
      let dictData = {}
      const rowsData = ddData.data.rows
      for (let i=0;i<rowsData.length;i++) {
        dictData[rowsData[i]['datadate']] = rowsData[i]['datavalue']
      }
      // 根绝x轴添加数据
      const xAxisData = indexParams.chartCurrentOption.xAxis.data
      indexParams.chartCurrentOption.series.push({
        name: ddData.name,
        yAxisIndex: indexParams.stackYasisPos,
        type: indexParams.stackSeriesType,
        symbol: 'none',
        connectNulls: true,
        data: xAxisData.map((xd) => {
          return dictData[xd]
        })
      })
      chartOne.setOption(indexParams.chartCurrentOption, { notMerge: true })
    })
  }

  // 获取季节图形配置
  const getSeasonChartOption = () => {
    GroupIndexChartOptionSeason(
      indexParams.currentIndexId,
      indexParams.seasonYears
    ).then((res) => {
      const resData = res.data
      indexParams.chartSeasonOption = resData.option
      chartTwo.setOption(indexParams.chartSeasonOption, { notMerge: true })
    })
  }
  // 获取区间图形配置
  const getIntervalChartOption = () => {
    GroupIndexChartOptionInterval(
      indexParams.currentIndexId,
      indexParams.intervalYears
    ).then((res) => {
      const resData = res.data
      indexParams.chartIntervalOption = resData.option
      chartThree.setOption(indexParams.chartIntervalOption, { notMerge: true })
    })
  }

  // 使用图形配置，设置数据表
  const setTableDataWithChartOption = () => {
    const xAxisData = indexParams.chartCurrentOption.xAxis.data
    const seriesData = indexParams.chartCurrentOption.series
    let tableData = []
    let tableColumns = [
      {prop: 'datadate', label: '日期'},
    ]
    let tempCol = []
    for (let i=0;i<xAxisData.length;i++) {
      let row = {
        datadate: xAxisData[i]
      }
      for (let j=0;j<seriesData.length;j++) {
        const sObj = seriesData[j]
        const colProp = 'c' + j
        row[colProp] = seriesData[j].data[i]
        if (tempCol.indexOf(colProp) < 0) {
          tableColumns.push({ prop: colProp, label: sObj.name })
          tempCol.push(colProp)
        }
      }
      tableData.push(row)
    }
    // tablePageChange(1) // 回到第一页
    indexParams.tableCurrentColumns = tableColumns
    indexParams.tableCurrentData = tableData.reverse()
  }

  // 显示数据的表格页码改变
  const tablePageChange = (page) => {
    indexParams.tablePage = page
    indexParams.tableStart = (indexParams.tablePage - 1) * indexParams.tablePageSize
    indexParams.tableEnd = indexParams.tableStart + indexParams.tablePageSize
    // console.log(page, indexParams.tableCurrentData.length, indexParams.tableStart, indexParams.tableEnd)
  }

  // 导出当前表格所有数据
  const exportTableToExcel = () => {
    // 重新构建数据,才有中文表头
    indexParams.exportLoading = true
    let excelData = []
    for (let i=0; i< indexParams.tableCurrentData.length; i ++) {
      let row = indexParams.tableCurrentData[i]
      let nrow = {}
      for (let j=0; j < indexParams.tableCurrentColumns.length; j++) {
        let col = indexParams.tableCurrentColumns[j]
        nrow[col.label] = row[col.prop]
      } 
      excelData.push(nrow)
    }
    let wb = XLSX.utils.book_new()
    let ws = XLSX.utils.json_to_sheet(excelData, { skipHeader: false})
    let timestamp = new Date().getTime()
    XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
    XLSX.writeFile(wb, timestamp + '.xlsx')
    indexParams.exportLoading = false
  }

  watch(()=>appRoute.query.igid, (nid) => {
    // 请求组下的指标数据
    // console.log(`请求id=${nid}组下的指标数据`)
    if (!nid) return
    // 获取该组下的指标列表
    GroupIndexes(nid).then((res) => {
      const data = res.data.data
      // 取19个展示，其他的放隐藏框
      const showIndexs = data.slice(0, 19)
      const hiddenIndexes = data.slice(19, )
      currentIndexes.showList = showIndexs
      currentIndexes.hiddenList = hiddenIndexes
      currentIndexes.isMore = hiddenIndexes.length > 0
    })
  }, { immediate: true })

  watch(() => appRoute.query.vcode, (ncode) => {
    if (!ncode || indexParams.isStack) return
    // 若未渲染图形，就渲染主要图
    // if (!indexParams.hasChartOption) {
    //   console.log('需要渲染主图')
    // }
    DataPrimaryIndex(ncode).then((res) => {
      const index = res.data.data
      if (index) {
        toClickIndexItem(index)
      }
    })
  }, { immediate: true })

  onMounted(() => {
    chartOne = echarts.init(chartOneBox.value) // [指定图形渲染的dom]
    chartTwo = echarts.init(chartTwoBox.value) // [季节图形渲染的dom]
    chartThree = echarts.init(chartThreeBox.value) // [区间图形]
    chartOne.setOption(noDataChartOption)
    chartTwo.setOption(noDataChartOption)
    chartThree.setOption(noDataChartOption)
  })
</script>
<template>
  <div class="page-view">
    <!-- 指标栏 -->
    <div class="index-box">
      <!-- 显示的box -->
      <div class="box-show">
        <span v-if="currentIndexes.showList.length < 1" class="no-index">该组别还没有数据</span>
        <div 
          v-for="idx in currentIndexes.showList"
          :key="idx.id"
          :title="idx.name"
          @click="toClickIndexItem(idx, true)"
        >{{ idx.name }}</div>
        <div 
          v-show="!currentIndexes.showMore && currentIndexes.hiddenList.length > 0"
          class="show-more" 
          @click="currentIndexes.showMore=true;"
        >
          <el-icon><ArrowDown /></el-icon>
          <span>更多</span>
        </div>
      </div>
      <!-- 隐藏box -->
      <div v-show="currentIndexes.showMore" class="box-hidden">
        <div v-for="idx in currentIndexes.hiddenList"
          :key="idx.id"
          :title="idx.name"
          @click="toClickIndexItem(idx, true)"
        >{{ idx.name }}</div>
        <div
          class="hidden-more"
          @click="currentIndexes.showMore=false"
        >
          <el-icon><ArrowUp /></el-icon>
          <span>收起</span>
        </div>
      </div>
    </div>
    <!-- 图表数据窗 -->
    <div class="index-content">
      <el-tabs
        v-model="indexParams.currentTabName"
      >
        <el-tab-pane label="图形" name="first">
          <div class="param-box">
            <el-space>
              <el-date-picker
                v-model="indexParams.dateRange"
                type="daterange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="YYYY-MM-DD"
                style="width: 220px"
                :shortcuts="dateRangeShortcuts"
                :unlink-panels="true"
                :clearable="false"                
              />
              <el-button type="primary" @click="toQueryIndexData">查询</el-button>
              <el-tooltip
                content="勾选后再次点击的指标数据将在图形上叠加可视化"
                placement="bottom-start"
              >
                <el-checkbox v-model="indexParams.isStack">图形叠加</el-checkbox>
              </el-tooltip>
              <div v-show="indexParams.isStack" class="stack-box">
                <span>指标数据以</span>
                <span>
                  <el-select
                    v-model="indexParams.stackSeriesType"
                    class="stack-select"
                    style="width: 80px;"
                  >
                    <el-option value="line" label="折线图" />
                    <el-option value="bar" label="柱形图" />
                  </el-select>
                </span>
                <span>叠加于</span>
                <span>
                  <el-select
                    v-model="indexParams.stackYasisPos"
                    class="stack-select"
                    style="width: 80px"
                  >
                    <el-option :value="0" label="左轴" />
                    <el-option :value="1" label="右轴" />
                  </el-select>
                </span>
              </div>
            </el-space>
          </div>
          <div class="charts-list">
            <div ref="chartOneBox" class="chart-box"></div>
            <div ref="chartTwoBox" class="chart-box"></div>
            <div ref="chartThreeBox" class="chart-box-row-cross"></div>
          </div>
        </el-tab-pane>
        <el-tab-pane label="数据" name="second">
          <div class="table-option">
            <div>
              <el-pagination
                small
                background
                hide-on-single-page
                layout="prev, pager, next"
                :page-size="indexParams.tablePageSize"
                :total="indexParams.tableCurrentData.length"
                @current-change="tablePageChange"
              />
            </div>
            <div class="download">
              <el-button
                icon="Download" 
                :loading="indexParams.exportLoading"
                @click="exportTableToExcel"
              >
                下载数据
              </el-button>
            </div>
          </div>
          <el-table
            border
            stripe 
            :data="indexParams.tableCurrentData.slice(indexParams.tableStart, indexParams.tableEnd)"
          >
            <el-table-column 
              v-for="col in indexParams.tableCurrentColumns" 
              :key="col.prop"
              :prop="col.prop"
              :label="col.label"
            />
          </el-table>
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>
<style scoped lang="scss">
  .page-view {
    .index-box {
      // width: 1117px;
      border-top: 1px solid #ebeef5;
      border-bottom: 1px solid #ebeef5;
      padding: 8px 10px;
      font-size: 14px;
      max-height: 500px;
      overflow-y: auto;
      background-color: #dce5f8;
      .box-show, .box-hidden {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        .no-index {
          color: #909399;
          padding-left: 50px;
          line-height: 35px;
        }
        div {
          // border: 1px solid #1e7db9;
          // box-shadow: 0 1px 2px #8fcaee inset, 0 -1px 0 #497897 inset, 0 -2px 3px #8fcaee inset;
          background: #88a1e0;
          color: #fff;
          border-radius: 4px;
          // background: -webkit-linear-gradient(top, #b1afaf, #fff);
          // background: -moz-linear-gradient(top, #f8c1b8, #fdd4cd);
          // background: linear-gradient(top, #f8c1b8, #fdd4cd);
          margin: 4px 8px 4px 0;
          padding: 3px 6px;
          width: 200px;
          text-overflow: ellipsis;
          overflow: hidden;
          white-space: nowrap;
          // border:1px solid #eaeaea;
          cursor: pointer;
          &:hover {
            color: $goldenColor;
            // background-color: #eaeaea;
          }
        }
        .show-more, .hidden-more{
          width: 200px;
          background-color: #dce5f8;
          border:none;
          display: flex;
          align-items: center;
          font-size: 11px;
          color: #909399;
          user-select: none;
          justify-content: flex-end;
          &:hover {
            color: #0072fc;
            background-color: #dce5f8;
          }
        }
      }
    }
    .index-content {
      margin-top: 6px;
      .param-box {
        display: flex;
        align-items: center;
        .stack-box {
          font-size: 14px;
          user-select: none;
          .stack-select {
            ::v-deep(.el-input__wrapper){
              border-radius: 0;
              box-shadow: 0 0 0 0 !important;
              &:hover {
                box-shadow: 0 0 0 0;
              }
            }
          }
        } 
      }
      .charts-list {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        margin-top: 16px;
        .chart-box {
          // box-shadow: 0px 0px 4px #eee;
          border-top: 1px solid #efefef;
          border-bottom: 1px solid #efefef;
          margin-left: 8px;
          margin-bottom: 16px;
          width: 548px;
          height: 333px;
        }
        .chart-box-row-cross {
          border-top: 1px solid #efefef;
          border-bottom: 1px solid #efefef;
          margin-top: 16px;
          margin-left: 8px;
          margin-bottom: 16px;
          width: 1105px;
          height: 500px;
        }
      }
      
      .table-option {
        margin-bottom: 16px;
        display: flex;
        align-items: center;
        .download {
          margin-left: auto;
        }
      }
    }
  }
</style>